<?php

namespace App\Models\Traits;

use App\Models\Reply;
use App\Models\Topic;
use Carbon\Carbon;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

trait ActiveUserHelper {
    protected $users = [];

    protected $topic_weight = 4;
    protected $reply_weight = 1;
    protected $pass_day = 7;

    protected $user_number = 6;

    protected $cache_key = 'luntan1_active_users';

    protected $cache_exprie_in_seconds = 65 * 60;

    public function getActiveUsers(){
        return Cache::remember($this->cache_key,$this->cache_exprie_in_seconds,function(){
            return $this->calculateActiveUsers();
        });
    }
    //获取活跃用户并存入缓存
    public function calculateAndCacheActiveUsers(){
        $active_users = $this->calculateActiveUsers();
        $this->cacheActiveUsers($active_users);
    }
    //计算活跃用户
    public function calculateActiveUsers(){
        $this->sumTopicScore();
        $this->sumReplyScore();
        $users = Arr::sort($this->users,function($user){
            return $user['score'];
        });
        $users = array_reverse($users,true);
        $users = array_splice($users,0,$this->user_number,true);
        $active_users = collect();

        foreach ($users as $user_id=>$user){
            $user = $this->find($user_id);
            if($user){
                $active_users->push($user);
            }
        }
        return $active_users;
    }

    //计算发帖的分数
    private function sumTopicScore() {
        $topic_users = Topic::query()->select(DB::raw('user_id,count(*) as topic_count'))
            ->where('created_at', '>=', Carbon::now()->subDays($this->pass_day))
            ->groupBy('user_id')
            ->get();
        foreach ($topic_users as $value) {
            $this->users[$value->user_id]['score'] = $value->topic_count * $this->topic_weight;
        }
    }

    private function sumReplyScore() {
        $reply_users = Reply::query()->select(DB::raw('user_id,count(*) as reply_count'))
            ->where('created_at', '>=', Carbon::now()->subDays($this->pass_day))
            ->groupBy('user_id')
            ->get();
        foreach ($reply_users as $value) {
            $reply_score = $value->reply_count * $this->reply_weight;
            if(isset($this->users[$value->user_id])){
                $this->users[$value->user_id]['score'] += $reply_score;
            }else{
                $this->users[$value->user_id]['score'] = $reply_score;
            }
        }
    }
    private function cacheActiveUsers($active_users){
        Cache::put($this->cache_key,$active_users,$this->cache_exprie_in_seconds);
    }
}
